class Vue {
  constructor(options) {
    this.$options = options || {}
    let data = this._data = options.data || undefined
    // 将data中数据都挂载到this上
    this._initData()
    // 将data中计算属性挂载到this上
    this._initComputed()
    // 将data中数据都进行响应化
    new Observer(data)
    // 添加监听到对应变量
    this._initWatch()
    // 将{{name}}这样的模板，使用data中数据替换掉
    new Compiler(options.el, this)
  }
  _initData() {
    // 这个函数功能很简单，就是把用户定义在data中的变量，都挂载到Vue实例上
    let that = this
    Object.keys(that._data).forEach(key => {
      Object.defineProperty(that, key, {
        get() {
          return that._data[key]
        },
        set(newVal) {
          that._data[key] = newVal
        }
      })
    })
  }
  _initComputed() {
    var that = this
    var computed = this.$options.computed || {}
    Object.keys(computed).forEach(function (key) {
      Object.defineProperty(that, key, {
        get: computed[key],
        set: function () {
          console.warn('no set')
        }
      })
    })
  }
  _initWatch() {
    var that = this
    var watch = this.$options.watch
    Object.keys(watch).forEach(function (key) {
      new Watch(that, key, watch[key])
    })
  }
}